home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1992 June: ROMin Holiday / ADC Developer CD (1992-06) (''ROMin Holiday'')_iso / Developer Connection - 06-1992.iso / Development Platforms / Apple II / Essentials / Apple IIGS SCSI Driver Shell / SCSI Main Driver < prev    next >
Encoding:
Text File  |  1990-09-14  |  24.8 KB  |  1,029 lines  |  [TEXT/MPS ]

  1.  
  2. ;*******************************************************
  3. ;
  4. ;    SCSI Driver 'Main Driver'.
  5. ;
  6. ;    Written by Matt Gulick.        Started May 25,1988
  7. ;
  8. ;    Copyright Apple Computer, Inc. 1988-90
  9. ;
  10. ;*******************************************************
  11.  
  12. ;*******************************************************
  13. ;
  14. ;    This file contains the 'Main Driver' as defined in
  15. ;    the ERS.
  16. ;
  17. ;*******************************************************
  18.  
  19. ;*******************************************************
  20. ;
  21. ;    Revision History:
  22. ;
  23. ;*******************************************************
  24.  
  25. ;    May 25,        1988    File started.
  26. ;    June 6,        1988    Turned sections into subroutines
  27. ;                        and wrote the Main Driver Proper.
  28. ;    June 20,    1988    Added Register Input and Output.
  29. ;                        Also included the changes from
  30. ;                        the code review.
  31. ;    Oct  25,    1988    Made changes in code to reflect the
  32. ;                        redesign of the SCSI Manager interface.
  33. ;
  34.  
  35.                     STRING        PASCAL
  36.                     BLANKS        OFF
  37.                     PAGESIZE    70
  38.                     PRINT        NOGEN
  39.                     PRINT        NOMDIR
  40.                     MACHINE        M65816
  41.  
  42.                     IMPORT        cmd_t_tbl
  43.                     IMPORT        call_type
  44.                     IMPORT        scratch0
  45.                     IMPORT        cmd_ps_tbl
  46.                     IMPORT        c_len_len
  47.                     IMPORT        c_blk_len
  48.                     IMPORT        divide
  49.                     IMPORT        result
  50.                     IMPORT        divend
  51.                     IMPORT        divsor
  52.                     IMPORT        time_cnt
  53.                     IMPORT        rout2_s_disp
  54.                     IMPORT        gsos_dpage
  55.                     IMPORT        f_partition
  56.                     IMPORT        internal
  57.                     IMPORT        disk_switch
  58.                     IMPORT        scsi_mgrnum
  59.                     IMPORT        manager_cmd
  60.                     IMPORT        cur_cmd
  61.                     IMPORT        cur_group
  62.                     IMPORT        trans_dest
  63.                     IMPORT        p_block_num
  64.                     IMPORT        killer_blk
  65.                     IMPORT        trans_flag
  66.                     IMPORT        temp_x
  67.                     IMPORT        temp_y
  68.                     IMPORT        timeout_flag
  69.                     IMPORT        auto_sense_data
  70.                     IMPORT        lst_rslt_stat
  71.                     IMPORT        lst_rslt_skey
  72.                     IMPORT        lst_rslt_info
  73.                     IMPORT        lst_rslt_rqlen
  74.                     IMPORT        lst_rslt_scode
  75.                     IMPORT        auto_sense_data
  76.                     IMPORT        auto_sense_data
  77.  
  78.                     PRINT        OFF
  79.  
  80.                     INCLUDE        'scsihd.equates'
  81.                     INCLUDE        'M16.MEMORY'
  82.                     INCLUDE        'M16.UTIL'
  83.  
  84.                     PRINT        ON
  85.  
  86.                     EJECT
  87.  
  88. ;*******************************************************
  89. ;
  90. ;    Main Entry point to the 'Main Driver'.
  91. ;
  92. ;    The function of this code is to take the callers
  93. ;    command data and build a SCSI Command Packet.  This
  94. ;    is done using the conversion tables in the file
  95. ;    'SCSI Command Table'.  The command and other data
  96. ;    is actually built in the space that has been added
  97. ;    to the DIB and then routed to the SCSI Manager.
  98. ;
  99. ;    The routine is called with the LONG pointer to the
  100. ;    callers command data in the Direct Page location
  101. ;    'scsi_mdrvr'.  This, in conjunction with the DIB Ptr
  102. ;    at direct page location 'dib_ptr' as the address
  103. ;    for the template overlay, will be used to do the
  104. ;    following:
  105. ;
  106. ;        Transfer the callers command data to the command
  107. ;        packet.
  108. ;            Zero all 12 bytes first.
  109. ;            Validate Internal Command flag if set.
  110. ;            .OR. in all values durring translation.
  111. ;            Adjust Transfer length if needed.
  112. ;            Convert Block Number from Logical to Actual
  113. ;                If partition Flag is ≠ zero then leave
  114. ;                block number unmodified.
  115. ;            Check for command errors.
  116. ;
  117. ;        Stuff SCSI Manager Flags
  118. ;
  119. ;        Stuff data in the TRX buffer data structure
  120. ;
  121. ;        Ship the call out to the SCSI Manager.
  122. ;
  123. ;        Clear Partition Call Flag.
  124. ;
  125. ;        Clear the Internal Command Flag.
  126. ;
  127. ;        Translate any SCSI errors into GS/OS errors.
  128. ;
  129. ;    Inputs:        Acc            =    Unspecified
  130. ;                Y register    =    Unspecified
  131. ;                X register    =    Unspecified
  132. ;                P register    =    0=M=X=e
  133. ;                Direct Page    =    Ours
  134. ;                Data Bank    =    Ours
  135. ;
  136. ;    Outputs:    Acc            =    Unspecified
  137. ;                Y register    =    Unspecified
  138. ;                X register    =    Unspecified
  139. ;                P register    =    0=M=X=e
  140. ;                Direct Page    =    Ours
  141. ;                Data Bank    =    Ours
  142. ;
  143. ;    Errors:        Carry set if Error.
  144. ;
  145. ;*******************************************************
  146.  
  147.                     EXPORT    main_drvr
  148. main_drvr            PROC
  149.                                             ;
  150.                                             ; Clear the Timeout flag
  151.                                             ;
  152.                     stz        |timeout_flag
  153.                                             ;
  154.                                             ; Clear the Command Buffer
  155.                                             ;
  156.                     ldx        #max_cmd_len*2\
  157.                             -2
  158.                     ldy        #max_cmd_len*2\
  159.                             +dib.scsicmd\
  160.                             -2
  161.                     lda        #$0000
  162. @loop                sta        [dib_ptr],y
  163.                     dey
  164.                     dey
  165.                     dex
  166.                     dex
  167.                     bpl        @loop
  168.                                             ;
  169.                                             ; Get the Current CoMmanD and GRouP
  170.                                             ;
  171.                     lda        [scsi_mdrvr]
  172.                     and        #$00ff
  173.                     sta        |cur_cmd        ;Preserve Current Command Number
  174.                     pha
  175.                                             ;
  176.                                             ; Get Offsets to Validate Command
  177.                                             ; Support by the device.
  178.                                             ;
  179.                     tax
  180.                     and        #bit_4\
  181.                             +bit_5\
  182.                             +bit_6\
  183.                             +bit_7
  184.                     lsr        a
  185.                     lsr        a
  186.                     lsr        a
  187.                     tay
  188.                     lda        |bm_cmd_offset,y
  189.                     tay
  190.                     txa
  191.                     and        #bit_0\
  192.                             +bit_1\
  193.                             +bit_2\
  194.                             +bit_3
  195.                     asl        a
  196.                     tax
  197.                     lda        [dib_ptr],y
  198.                     and        |bm_cmd_mask,x
  199.                     bne        @cmd_support
  200.                                             ;
  201.                                             ; Command Not Supported
  202.                                             ; by this device.
  203.                                             ;
  204.                     pla                            ;Fix Stack
  205.                     lda        #drvr_bad_code
  206.                     sec
  207.                     rts
  208.                                             ;
  209.                                             ; Get the SCSI Group Number.
  210.                                             ;
  211. @cmd_support        pla
  212.                     and        #bit_5\
  213.                             +bit_6\
  214.                             +bit_7
  215.                     lsr        a
  216.                     lsr        a
  217.                     lsr        a
  218.                     lsr        a
  219.                     lsr        a
  220.                     sta        |cur_group
  221.                                             ;
  222.                                             ; Set TRANSlation PoiNTer
  223.                                             ;
  224.                     jsr        s_trans_ptr
  225.                     bcs        @exit_far
  226.                                             ;
  227.                                             ; VALidate the CoMmanD TYPe
  228.                                             ;
  229.                     jsr        val_cmd_typ
  230.                     bcs        @exit_far        ;Bad Command
  231.                                             ;
  232.                                             ; Set 'scsi_zp4' to scsi Command
  233.                                             ; in DIB
  234.                                             ;
  235.                     clc
  236.                     lda        <dib_ptr
  237.                     adc        #dib.scsicmd
  238.                     sta        <scsi_zp4
  239.                     lda        <dib_ptr+2
  240.                     adc        #$0000
  241.                     sta        <scsi_zp4+2
  242.                                             ;
  243.                                             ; TRANSLATE user's command data
  244.                                             ; into SCSI Command Packet
  245.                                             ;
  246.                     jsr        translate
  247.                                             ;
  248.                                             ; FINALIZE the SCSI Command Packet.
  249.                                             ; This includes updating the
  250.                                             ; requested block number to account
  251.                                             ; for partitioning, and the request
  252.                                             ; length from bytes to blocks.
  253.                                             ;
  254.                     jsr        finalize
  255. @exit_far            bcs        @exit
  256.                     bvs        @no_data
  257.                                             ;
  258.                                             ; Stuff SCSI Manager flags.
  259.                                             ;
  260.                     jsr        stuff_flag
  261.                                             ;
  262.                                             ; Build the Transmit/Receive
  263.                                             ; structure.
  264.                                             ;
  265.                     lda        #scsi_io_call    ;set SCSI Manager Command to
  266.                     sta        |manager_cmd    ;I/O Call.
  267.  
  268.                     ldy        #dib.trx_buff    ;Stuff the Buffer Pointer
  269.                     lda        <buff_ptr
  270.                     sta        [dib_ptr],y
  271.  
  272.                     ldy        #dib.trx_buff+2
  273.                     lda        <buff_ptr+2
  274.                     sta        [dib_ptr],y
  275.                                             ;
  276.                                             ; Stuff the request count in both the
  277.                                             ; Total length and in the DCMove command.
  278.                                             ;
  279.                     lda        <rqst_cnt
  280.  
  281.                     ldy        #dib.trx_length    ;Stuff the DCMove transfer count
  282.                     sta        [dib_ptr],y
  283.  
  284.                     ldy        #dib.trx_rqst    ;Stuff the Requested transfer count
  285.                     sta        [dib_ptr],y
  286.  
  287.                     lda        <rqst_cnt+2
  288.  
  289.                     ldy        #dib.trx_length+2
  290.                     sta        [dib_ptr],y
  291.  
  292.                     ldy        #dib.trx_rqst+2
  293.                     sta        [dib_ptr],y
  294.                                             ;
  295.                                             ; Mark auto sense buffer as trashed.
  296.                                             ;
  297.                     stz        |auto_sense_data
  298.                     stz        |auto_sense_data+2
  299.                                             ;
  300.                                             ; Send command to the SCSI Manager
  301.                                             ;
  302.                     jsr        issue_cmd
  303.                                             ;
  304.                                             ; Place Info in for Get Last Result
  305.                                             ; Status Call.
  306.                                             ;
  307.                     php
  308.                     pha
  309.  
  310.                     sta        |lst_rslt_stat
  311.                                             ;
  312.                                             ; Did we get auto sense data?
  313.                                             ;
  314.                     lda        |auto_sense_data
  315.                     ora        |auto_sense_data+2
  316.                     beq        @no_sense        ;No.
  317.                                             ;
  318.                                             ; Yes we did.  Setup last result
  319.                                             ; info incase it is needed.
  320.                                             ;
  321.                     lda        |auto_sense_data+\
  322.                             rqst_sens.sense_key
  323.                     and        #$00ff
  324.                     sta        |lst_rslt_skey
  325.  
  326.                     lda        |auto_sense_data+\
  327.                             rqst_sens.info_bytes
  328.                     sta        |lst_rslt_info
  329.                     lda        |auto_sense_data+\
  330.                             rqst_sens.info_bytes+2
  331.                     sta        |lst_rslt_info+2
  332.  
  333.                     clc
  334.                     lda        |auto_sense_data+\
  335.                             rqst_sens.addnl_sens_len
  336.                     and        #$00ff
  337.                     adc        #$0008
  338.                     sta        |lst_rslt_rqlen
  339.  
  340.                     lda        |auto_sense_data+\
  341.                             rqst_sens.addnl_sens_code
  342.                     and        #$00ff
  343.                     sta        |lst_rslt_scode
  344.                                             ;
  345.                                             ; Restore Acc. Carry and Stack.
  346.                                             ;
  347. @no_sense            pla
  348.                     plp
  349.                                             ;
  350.                                             ; Clear partiton call and internal
  351.                                             ; command flags.
  352.                                             ;
  353. @no_data            stz        |f_partition
  354.                     stz        |internal
  355.                                             ;
  356.                                             ; return to Driver front end.
  357.                                             ;
  358. @exit                rts
  359.  
  360. ;*******************************************************
  361. ;
  362. ; Transfer the callers command data to the command
  363. ; packet.
  364. ;
  365. ;*******************************************************
  366.  
  367. ;*******************************************************
  368. ;*******************************************************
  369. ;
  370. ;    Subroutines from the Main Driver.
  371. ;
  372. ;*******************************************************
  373. ;*******************************************************
  374.  
  375.                     EJECT
  376.             
  377. ;*******************************************************
  378. ;
  379. ;    Point to Command Translation Table
  380. ;        'trans_flag'    =    Translation Flags
  381. ;        'scsi_zp2'        =    Translation Data.
  382. ;
  383. ;*******************************************************
  384.  
  385.  
  386. s_trans_ptr            lda        #cmd_t_tbl
  387.                     sta        <scsi_zp2
  388.                                         ;
  389.                                         ; Find Command Translation Table for conversion
  390.                                         ;
  391. @find_cmd            lda        (scsi_zp2)
  392.                     bmi        @chk_end
  393.                     cmp        |cur_cmd
  394.                     beq        @got_r_cmd
  395.                                         ;
  396.                                         ; Goto next entry.
  397.                                         ;
  398.                     clc
  399.                     lda        <scsi_zp2
  400.                     adc        #$0004
  401.                     sta        <scsi_zp2
  402.                     bra        @find_cmd
  403.                                         ;
  404.                                         ; Is it really the end of the table?
  405.                                         ;
  406. @chk_end            cmp        #$ffff
  407.                     beq        @no_cmd_fnd
  408.                                         ;
  409.                                         ; The Command was not found.
  410.                                         ; Return a Bad Command error
  411.                                         ;
  412. @no_cmd_fnd            lda        #drvr_bad_code
  413.                     sec
  414.                     rts
  415.                                         ;
  416.                                         ; We found our command.  Now
  417.                                         ; point to the translation data.
  418.                                         ;
  419. @got_r_cmd            ldy        #$0002
  420.                     lda        (scsi_zp2),y
  421.                     sta        <scsi_zp2
  422.                                         ;
  423.                                         ; Now get the Translation Flags.
  424.                                         ;
  425.                     lda        (scsi_zp2)
  426.                     sta        |trans_flag
  427.                                         ;
  428.                                         ; Set Timeout Factor.
  429.                                         ;
  430. @check_timer        and        #scsic_tout
  431.                     beq        @not_by_block
  432.  
  433.                     dec        |timeout_flag
  434.  
  435. @not_by_block        ldy        #$0002
  436.                     lda        (scsi_zp2),y
  437.                     ldy        #dib.time_out
  438.                     sta        [dib_ptr],y
  439.                                         ;
  440.                                         ; Advance pointer to translation data
  441.                                         ;
  442.                     clc
  443.                     lda        <scsi_zp2
  444.                     adc        #$0004            ;Setup Pointer to translation data
  445.                     sta        <scsi_zp2
  446.                     rts
  447.  
  448.                     EJECT
  449.             
  450. ;*******************************************************
  451. ;
  452. ;    Check to see if this is an internal command.  If it
  453. ;    is, then the high of 'internal' must be set.
  454. ;
  455. ;    Validate that this command is a Staus Command if we
  456. ;    were called with a Status type call.  Or is it a
  457. ;    Control call with a Control Command?
  458. ;
  459. ;*******************************************************
  460.  
  461.  
  462. val_cmd_typ            stz        |disk_switch        ;Ensure that this flag is clear.
  463.  
  464.                     lda        |trans_flag
  465.                     tay
  466.                     and        #scsic_int
  467.                     beq        @non_int        ;If = then Internal Command flag = 0
  468.                     bit        |internal        ;non-0.  Is it an internal command?
  469.                     bpl        @no_cmd_fnd
  470.                                             ;
  471.                                             ; Is the command a Status if entry
  472.                                             ; was via status, or is it a Control
  473.                                             ; vial control entry.  If neither
  474.                                             ; then error out.
  475.                                             ;
  476. @non_int            tya
  477.                     and        |call_type
  478.                     beq        @no_cmd_fnd        ;No match.  Error.
  479.                                             ;
  480.                                             ; Must this command be issued to the
  481.                                             ; first DIB of a linked device?
  482.                                             ;
  483.                     tya
  484.                     and        #scsic_1st
  485.                     beq        @chk_dsksw
  486.                                             ;
  487.                                             ; Check Headlink Pointer.
  488.                                             ;
  489.                     phy
  490.                     ldy        #dib.headlnk
  491.                     lda        [dib_ptr],y
  492.                     beq        @ply
  493.                     ldy        #dib.devnum
  494.                     cmp        [dib_ptr],y
  495.                     beq        @ply
  496.                                             ;
  497.                                             ; The Command was invalid.
  498.                                             ; Return a Bad Command error
  499.                                             ;
  500.                     ply                        ;Restore the stack.
  501. @bad_dev_num        lda        #bad_dev_number
  502.                     sec
  503.                     rts
  504.                                             ;
  505.                                             ; Check to see if we need to do a
  506.                                             ; DISK SWITCH after this command.
  507.                                             ;
  508. @ply                ply
  509.  
  510. @chk_dsksw            tya
  511.                     and        #scsic_dsw
  512.                     beq        @clc
  513.  
  514.                     dec        disk_switch
  515.  
  516. @clc                clc
  517.                     rts
  518.                                             ;
  519.                                             ; The Command was invalid.
  520.                                             ; Return a Bad Command error
  521.                                             ;
  522. @no_cmd_fnd            lda        #drvr_bad_code
  523.                     sec
  524. @rts                rts
  525.  
  526.                     EJECT
  527.             
  528. ;*******************************************************
  529. ;
  530. ;    Is it an ASIS Command, or does it need to be
  531. ;    translated?  What ever the case, when this command
  532. ;    returns, the command data will be in it's place
  533. ;    ready for the length and block fields to be updated
  534. ;    if needed.
  535. ;
  536. ;*******************************************************
  537.  
  538.  
  539. translate            lda        |trans_flag
  540.                     and        #scsid_asis
  541.                     beq        @translate
  542.                                                 ;
  543.                                                 ; Yes. It is as is.  Move the Command
  544.                                                 ; bytes over.
  545.                                                 ;
  546.                     ldy        #max_cmd_len-2
  547. @move_cmd            lda        [scsi_mdrvr],y
  548.                     sta        [scsi_zp4],y
  549.                     dey
  550.                     dey
  551.                     bpl        @move_cmd
  552. @rts                rts                            ;Return to caller.
  553.                                                 ;
  554.                                                 ;
  555.                                                 ; We have gotten to this piece of code
  556.                                                 ; because the user data is not in the
  557.                                                 ; form accepted by the SCSI Target.
  558.                                                 ; We need to translate the data using
  559.                                                 ; the translation data pointed to by
  560.                                                 ; the direct page value 'scsi_zp2' It
  561.                                                 ; is extremely important that we .OR.
  562.                                                 ; in all values during translation.
  563.                                                 ;
  564. @translate            lda        #null                ;Always do the Command Byte
  565.                     bra        @over
  566.  
  567. @loop                lda        (scsi_zp2)            ;Get translation Data.
  568.                     beq        @rts                ;we are at the end if value = $0000
  569.                                                 ;
  570.                                                 ; Place High Byte in Source Offset and
  571.                                                 ; the Low Byte in Destination Offset.
  572.                                                 ;
  573. @over                tay
  574.                     and        #bit_0\
  575.                             +bit_1\
  576.                             +bit_2\
  577.                             +bit_3
  578.                     sta        |trans_dest
  579.                     tya
  580.                     xba                            ;Move High Byte to Low Byte
  581.                     and        #bit_0\
  582.                             +bit_1\
  583.                             +bit_2\
  584.                             +bit_3
  585.                     tay
  586.                                                 ;
  587.                                                 ; Move Command Data.
  588.                                                 ;
  589.                     shortm                        ;We only want the byte from this
  590.                     lda        [scsi_mdrvr],y
  591.                     ldy        |trans_dest            ;offset.
  592.                     ora        [scsi_zp4],y
  593.                     sta        [scsi_zp4],y
  594.                     longm
  595.                                                 ;
  596.                                                 ; Point to next Translation Byte
  597.                                                 ;
  598.                     clc
  599.                     lda        <scsi_zp2
  600.                     adc        #$0002
  601.                     sta        <scsi_zp2
  602.                     bra        @loop
  603.  
  604.                     EJECT
  605.             
  606. ;*******************************************************
  607. ;
  608. ;    The command Packet is now built except for some
  609. ;    minor cosmetic work.
  610. ;
  611. ;*******************************************************
  612.                                             ;
  613.                                             ; Stuff the SCSI Device ID (Our unit
  614.                                             ; number) and our Slot Number into the
  615.                                             ; commad area for the SCSI Manager.
  616.                                             ;
  617. finalize
  618.                     ldy        #dib.slotnum
  619.                     lda        [dib_ptr],y
  620.                     ldy        #dib.scsi_slot
  621.                     sta        [dib_ptr],y
  622.  
  623.                     ldy        #dib.unitnum
  624.                     lda        [dib_ptr],y
  625.                     and        #max_p_mask\
  626.                             --$ffff
  627.                     ldy        #dib.scsiid
  628.                     sta        [dib_ptr],y
  629.                                             ;
  630.                                             ; Set ZP3 to point to the Command
  631.                                             ; Packet information.  This will be
  632.                                             ; used to place the length and
  633.                                             ; block number as well as the
  634.                                             ; command length for the SCSI
  635.                                             ; Manager.
  636.                                             ;
  637.                     lda        |cur_group
  638.                     asl        a                ;Multiply by 6
  639.                     sta        |scratch0
  640.                     asl        a
  641.                     adc        |scratch0        ;Carry Clear by asl and adc.
  642.                     adc        #cmd_ps_tbl        ;Carry still Clear.
  643.                     sta        <scsi_zp3
  644.                                             ;
  645.                                             ; Adjust Transfer length if needed.
  646.                                             ;
  647.                     lda        trans_flag
  648.                     and        #scsid_blk++\    ;Convert Trans Count to Blocks
  649.                             scsid_byte++\    ;Leave Trans Count in Bytes
  650.                             scsid_none        ;Transfer count does not go in CMD
  651.  
  652.                     cmp        #scsid_none        ;Is the Request length in the command?
  653.                     beq        @blknum_jmp        ;No.
  654.                     cmp        #scsid_byte        ;Yes.  Is it in Byte form?
  655.                     beq        @move_byte        ;Yes.
  656.                     cmp        #scsid_blk        ;No.  Is it in Block form?
  657.                     beq        @move_blk        ;Yes.
  658.                     sec                        ;No. Return Bad Byte Count Error.
  659. @bad_rqst            lda        #drvr_bad_cnt
  660. @clv                clv                        ;Clear Overflow Flag
  661.                     rts
  662.  
  663. @blknum_jmp            jmp        @block_num        ;No.
  664.                                             ;
  665.                                             ; If the request count = 0 then exit with
  666.                                             ; the overflow flag set.  This will indicate
  667.                                             ; that no data is to tbe transfered.  It
  668.                                             ; also indicates that this is not an error
  669.                                             ; condition.
  670.                                             ;
  671. @zero_cnt            bit        @overflow
  672.                     clc
  673.                     rts
  674.  
  675. @overflow            dc.w    $4000
  676.                                             ;
  677.                                             ; Convert Request Count to Blocks.
  678.                                             ;
  679. @move_blk            lda        <rqst_cnt        ;Setup Divide Routine.
  680.                     sta        |divend
  681.  
  682.                     ora        <rqst_cnt+2        ;Check for zero request from block device.
  683.                     beq        @zero_cnt
  684.  
  685.                     lda        <rqst_cnt+2
  686.                     sta        |divend+2
  687.  
  688.                     ldy        #dib.blksize
  689.                     lda        [dib_ptr],y
  690.                     sta        |divsor
  691.  
  692.                     jsr        divide
  693.                     bcs        @clv
  694.                                             ;
  695.                                             ; Get requested Length in blocks and
  696.                                             ; goto stuff routine. Also stuff for
  697.                                             ; timeout calculation if needed.
  698.                                             ;
  699.                     ldx        |result
  700.                     stx        |time_cnt
  701.                     ldy        |result+2
  702.                     sty        |time_cnt+2
  703.  
  704.                     bra        @stuff_len
  705.                                             ;
  706.                                             ; Get requested length in bytes and goto
  707.                                             ; stuff routine.
  708.                                             ;
  709. @move_byte            ldx        <rqst_cnt
  710.                     ldy        <rqst_cnt+2
  711.                                             ;
  712.                                             ; Clear timeout Values.
  713.                                             ;
  714.                     stz        |time_cnt
  715.                     stz        |time_cnt+2
  716.  
  717. ;*******************************************************
  718. ;
  719. ;    Transfer request length to command packet.
  720. ;
  721. ;*******************************************************
  722.  
  723. @stuff_len            sty        |temp_y            ;Save 32 bit transfer length for later
  724.                     stx        |temp_x
  725.                     short                    ;Goto 8 bit Acc
  726.                     ldy        #<c_len_len        ;Get offset into command packet description
  727.                     lda        (scsi_zp3),y    ;table and get Length of length field
  728.                     tax
  729.                                             ;
  730.                                             ; Check byte count so that any value greater
  731.                                             ; than the max will be represented by the
  732.                                             ; max.
  733.                                             ;
  734.                     lda        |temp_y+1
  735.                     beq        @byte_3_ok
  736.                     lda        #$ff
  737.                     stz        |temp_y+1
  738.                     sta        |temp_y
  739.                     sta        |temp_x+1
  740.                     sta        |temp_x
  741. @byte_3_ok            cpx        #$03
  742.                     bge        @count_ok
  743.  
  744.                     lda        |temp_y
  745.                     beq        @byte_2_ok
  746.                     lda        #$ff
  747.                     stz        |temp_y
  748.                     sta        |temp_x+1
  749.                     sta        |temp_x
  750. @byte_2_ok            cpx        #$02
  751.                     beq        @count_ok
  752.  
  753.                     lda        |temp_x+1
  754.                     beq        @byte_1_ok
  755.                     lda        #$ff
  756.                     stz        |temp_x+1
  757.                     sta        |temp_x
  758. @byte_1_ok            cpx        #$01
  759.                     beq        @count_ok
  760.  
  761.                     stz        |temp_x
  762.  
  763. @count_ok            dey
  764.                     lda        (scsi_zp3),y    ;and the offset to the end of the length
  765.                     tay                        ;field
  766.                     lda        |temp_x            ;Stuff the Low byte of the length
  767.                     ora        [scsi_zp4],y
  768.                     sta        [scsi_zp4],y
  769.                     dex
  770.                     beq        @exit_len        ;Do Block Number.
  771.                     dey
  772.                     lda        |temp_x+1        ;Stuff the Mid-Low byte of the
  773.                     ora        [scsi_zp4],y    ;length if used.
  774.                     sta        [scsi_zp4],y
  775.                     dex
  776.                     beq        @exit_len        ;Do Block Number.
  777.                     dey
  778.                     lda        |temp_y            ;Stuff the Mid-High byte of the
  779.                     ora        [scsi_zp4],y    ;length if used.
  780.                     sta        [scsi_zp4],y
  781.                     dex
  782.                     beq        @exit_len        ;Do Block Number.
  783.                     dey
  784.                     lda        |temp_y+1        ;Stuff the High byte of the
  785.                     ora        [scsi_zp4],y    ;length if used.
  786.                     sta        [scsi_zp4],y
  787.                                             ;
  788.                                             ; Clean up Processor.
  789.                                             ;
  790. @exit_len            longmx
  791.  
  792. ;*******************************************************
  793. ;
  794. ;    Convert Block Number from Logical to Actual If
  795. ;    partition Flag is ≠ zero then leave block number
  796. ;    unmodified.
  797. ;
  798. ;*******************************************************
  799.  
  800. @block_num            lda        |trans_flag        ;Does it have a block number in the
  801.                     and        #scsit_blk        ;command packet?
  802.                     beq        @exit_blk1        ;No.
  803.                                             ;
  804.                                             ; Is this a partition Map call?
  805.                                             ;
  806.                     bit        |f_partition    ;Get the partition call flag.
  807.                     bmi        @exit_blk1        ;It's a partition map call.
  808.                                             ;
  809.                                             ; It has a block number and is not a
  810.                                             ; partition map command.  Translate
  811.                                             ; that logical block number to a
  812.                                             ; physical number.
  813.                                             ;
  814.                     ldy        #dib.start_blk+2
  815.                     lda        [dib_ptr],y
  816.                     sta        |p_block_num\    ;Stored High » Low
  817.                             -dib.start_blk,y
  818.                     ldy        #dib.start_blk
  819.                     lda        [dib_ptr],y
  820.                     sta        |p_block_num\    ;Stored High » Low
  821.                             -dib.start_blk,y
  822.                                             ;
  823.                                             ; Zero out starting block number space.
  824.                                             ; This space is used to retrieve the
  825.                                             ; starting block number for a call incase
  826.                                             ; it is needed.  An example of this is a
  827.                                             ; device specific write type call that is
  828.                                             ; going to update blocks that might be in
  829.                                             ; the cache.  If this happens, then this
  830.                                             ; will be used as a starting point from
  831.                                             ; whence to kill those blocks that are in
  832.                                             ; the cache.
  833.                                             ;
  834.                     stz        |killer_blk
  835.                     stz        |killer_blk+2
  836.                                             ;
  837.                                             ; We now have the block offset where we
  838.                                             ; need it.
  839.                                             ;
  840.                     short                    ;Goto 8 bit Acc
  841.                     ldy        #<c_blk_len        ;Get offset into command packet description
  842.                     lda        (scsi_zp3),y    ;table and get Length of block field
  843.                     tax
  844.                     dey
  845.                     lda        (scsi_zp3),y    ;and the offset to the end of the block
  846.                     tay                        ;field
  847.                     clc
  848.                     lda        [scsi_zp4],y    ;adjust the Low byte of block num.
  849.                     sta        |killer_blk
  850.                     adc        |p_block_num+3    ;add the physical block offset.
  851.                     sta        [scsi_zp4],y
  852.                     dex
  853.                     beq        @exit_blk        ;Do Block Number.
  854.                     dey
  855.                     lda        [scsi_zp4],y    ;adjust the Mid-Low byte of block num.
  856.                     sta        |killer_blk+1
  857.                     adc        |p_block_num+2    ;add the physical block offset.
  858.                     sta        [scsi_zp4],y
  859.                     dex
  860.                     beq        @exit_blk        ;Do Block Number.
  861.                     dey
  862.                     lda        [scsi_zp4],y    ;adjust the Mid-High byte of block num.
  863.                     sta        |killer_blk+2
  864.                     adc        |p_block_num+1        ;add the physical block offset.
  865.                     sta        [scsi_zp4],y
  866.                     dex
  867.                     beq        @exit_blk            ;Do Block Number.
  868.                     dey
  869.                     lda        [scsi_zp4],y        ;adjust the High byte of block num.
  870.                     sta        |killer_blk+3
  871.                     adc        |p_block_num        ;add the physical block offset.
  872.                     sta        [scsi_zp4],y
  873.                                                 ;
  874.                                                 ; Clean up Processor.
  875.                                                 ;
  876. @exit_blk            longmx
  877.                                                 ;
  878.                                                 ; Check for Block Number overflow
  879.                                                 ; (Carry Set)
  880.                                                 ;
  881.                     bcc        @exit_blk2
  882.                     lda        #drvr_bad_req
  883.                     rts
  884.             
  885. @exit_blk1            clc
  886. @exit_blk2            clv                            ;Clear no data flag
  887.                     rts
  888.  
  889.                     EJECT
  890.             
  891. ;*******************************************************
  892. ;
  893. ;    Stuff Flags for SCSI Manager
  894. ;
  895. ;*******************************************************
  896.  
  897. stuff_flag            lda        #null
  898.  
  899.                     ldy        #dib.scsic_flgs
  900.                     sta        [dib_ptr],y
  901.                     rts
  902.  
  903.                     EJECT
  904.             
  905. ;*******************************************************
  906. ;
  907. ;    Call the SCSI Manager VIA the Supervisory Dispatcher.
  908. ;
  909. ;*******************************************************
  910. issue_cmd
  911.                                                 ;
  912.                                                 ; Set Timeout Factor.
  913.                                                 ;
  914.                 lda        |timeout_flag
  915.                 beq        @over
  916.                                                 ;
  917.                                                 ; Adjust Time Out Value.
  918.                                                 ;
  919.                 ldy        #dib.time_out
  920.                 lda        [dib_ptr],y
  921.                 sta        @time_mult
  922.  
  923.                 lda        |time_cnt+2
  924.                 bne        @do_max_time
  925.                 lda        |time_cnt
  926.                 stz        |time_cnt
  927.  
  928. @mult_loop        lsr        @time_mult
  929.                 bcc        @shift
  930.  
  931.                 php
  932.                 clc
  933.                 adc        |time_cnt
  934.                 sta        |time_cnt
  935.                 bcs        @fix
  936.                 cmp        #max_timeout
  937.                 bge        @fix
  938.                 plp
  939.  
  940. @shift            beq        @save
  941.                 asl        a
  942.                 bcc        @mult_loop
  943.                 bra        @do_max_time
  944.  
  945. @time_mult        dc.w    null
  946.  
  947. @fix            plp
  948.  
  949. @do_max_time    lda        #max_timeout
  950. @save            ldy        #dib.time_out
  951.                 sta        [dib_ptr],y
  952.                                                 ;
  953.                                                 ; Setup the pointer to our Command
  954.                                                 ; list within the DIB on GS/OS Direct
  955.                                                 ; Page
  956.                                                 ;
  957. @over            ldx        |gsos_dpage
  958.                 clc
  959.                 lda        <dib_ptr
  960.  
  961.                 adc        #dib.scsi_slot
  962.  
  963.                 sta        >smgr_pl_ptr,x
  964.                 lda        <dib_ptr+2
  965.  
  966.                 adc        #^dib.scsi_slot
  967.  
  968.                 sta        >smgr_pl_ptr+2,x
  969.                                                 ;
  970.                                                 ; Call the SCSI Manager via the
  971.                                                 ; S_DISPATCHER
  972.                                                 ;
  973.                 lda        |scsi_mgrnum            ;Get the Managers ID
  974.                 ldx        |manager_cmd            ;Get Manager Command Number
  975.                 jmp        rout2_s_disp
  976.  
  977.                 EJECT
  978.                                                 ;
  979.                                                 ; Bitmaps used to check
  980.                                                 ; for command errors.
  981.                                                 ;
  982.                                                 ; Offset into DIB to where
  983.                                                 ; the WORD is that holds the
  984.                                                 ; bit for this group.
  985.                                                 ;
  986. bm_cmd_offset    dc.w    dib.group0                ;group0    Low  WORD
  987.                 dc.w    dib.group0+2            ;        High WORD
  988.                 dc.w    dib.group1                ;group1    Low  WORD
  989.                 dc.w    dib.group1+2            ;        High WORD
  990.                 dc.w    dib.group2                ;group2    Low  WORD
  991.                 dc.w    dib.group2+2            ;        High WORD
  992.                 dc.w    dib.group3                ;group3    Low  WORD
  993.                 dc.w    dib.group3+2            ;        High WORD
  994.                 dc.w    dib.group4                ;group4    Low  WORD
  995.                 dc.w    dib.group4+2            ;        High WORD
  996.                 dc.w    dib.group5                ;group5    Low  WORD
  997.                 dc.w    dib.group5+2            ;        High WORD
  998.                 dc.w    dib.group6                ;group6    Low  WORD
  999.                 dc.w    dib.group6+2            ;        High WORD
  1000.                 dc.w    dib.group7                ;group7    Low  WORD
  1001.                 dc.w    dib.group7+2            ;        High WORD
  1002.                                                 ;
  1003.                                                 ; Mask for commands $00 - $0F
  1004.                                                 ; in the low word and commands
  1005.                                                 ; $10 - $1F in the high word.
  1006.                                                 ;
  1007. bm_cmd_mask        dc.w    bit_7                    ;CMD $x0 Bit 7 Low Byte
  1008.                 dc.w    bit_6                    ;CMD $x1 Bit 6 Low Byte
  1009.                 dc.w    bit_5                    ;CMD $x2 Bit 5 Low Byte
  1010.                 dc.w    bit_4                    ;CMD $x3 Bit 4 Low Byte
  1011.                 dc.w    bit_3                    ;CMD $x4 Bit 3 Low Byte
  1012.                 dc.w    bit_2                    ;CMD $x5 Bit 2 Low Byte
  1013.                 dc.w    bit_1                    ;CMD $x6 Bit 1 Low Byte
  1014.                 dc.w    bit_0                    ;CMD $x7 Bit 0 Low Byte
  1015.                 dc.w    bit_15                    ;CMD $x8 Bit 7 High Byte
  1016.                 dc.w    bit_14                    ;CMD $x9 Bit 6 High Byte
  1017.                 dc.w    bit_13                    ;CMD $xA Bit 5 High Byte
  1018.                 dc.w    bit_12                    ;CMD $xB Bit 4 High Byte
  1019.                 dc.w    bit_11                    ;CMD $xC Bit 3 High Byte
  1020.                 dc.w    bit_10                    ;CMD $xD Bit 2 High Byte
  1021.                 dc.w    bit_9                    ;CMD $xE Bit 1 High Byte
  1022.                 dc.w    bit_8                    ;CMD $xF Bit 0 High Byte
  1023.  
  1024.                 ENDP
  1025.  
  1026.                 EJECT
  1027.  
  1028.                 END
  1029.